#ifndef CONFIG_FILE_H_
#define CONFIG_FILE_H_

#include <cm/cm_constant.h>
#include <cm/cm_str.h>

#include <stddef.h>
#include <stdlib.h>
#include <ctype.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Content of a configuration file
 * ...
 * #some commentary
 * [section]
 * key1=value1
 * key2=value2
 * [section2]
 * ...
 */

/*
 * size of one section:
 * MAX_ITEM_PER_SECTION * (2 * LEN_MAX_ITEM_NAME) + LEN_MAX_SECTION_NAME
 * here it's 4K
 */
#define LEN_MAX_ITEM_NAME (64)
#define LEN_MAX_SECTION_NAME (128)
#define MAX_ITEM_PER_SECTION (31)
#define MAX_SECTION_PER_FILE (32)

typedef struct config_file cfg_t;

/*
 * @brief	打开一个配置文件，并返回配置文件描述结构体cfg_t的一个指针
 * @param	path：配置文件路径+文件名
 * @param	size：为该配置文件创建多少个段，一旦确定后则该配置文件最大只能读取size个段
 */
cfg_t* cfg_open(const char *path, int size);

/*
 * @brief	刷新配置文件，将导致文件内容被重新写入磁盘
 */
void cfg_flush(cfg_t *cfg);

/*
 * @brief	销毁配置文件并释放空间，该函数返回后 *cfg 置为NULL
 */
void cfg_close(cfg_t **cfg);

/*
 * @brief	打印配置文件信息，调试用
 */
void cfg_printf(cfg_t *file);

/*
 * @brief	从配置文件cfg中获取段名称为section，键名称为key的配置值。
 * 		value处的空间用户分配，且大小至少为size
 * 		返回结果保存在value处，如果获取成功则返回value处有效字节数，失败则返回-1
 */
int cfg_getvalue(const cfg_t *cfg, const char *section, const char *key,
		char *value, size_t size);

/*
 * @brief	将配置文件cfg中段名称为section，键名称为key处的值设置为字符串value
 * @return	成功返回0，失败返回-1
 */
int cfg_setvalue(cfg_t *cfg, const char *section, const char *key,
		const char *value);

/*
 * @brief	向配置文件中添加一个键值对，段名称为section
 */
int cfg_addvalue(cfg_t *cfg, const char *section, const char *key,
		const char *value);

#ifdef __cplusplus
}
#endif

#endif /* CONFIG_FILE_H_ */
